﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using LCA.Community.DAL.Model;
using LCA.Community.DAL.Interfaces;
using Microsoft.Practices.Unity;
using System.Globalization;

namespace LCA.Community.DAL
{
    public class TextDataLoader : IDataLoader
    {
        private readonly string QUESTIONS_FILE = "questions.txt";
        private readonly string ANSWERS_FILE = "answers.txt";
        private readonly string ANSWERSVOTES_FILE = "answersvotes.txt";
        private readonly string VOLUNTEERS_FILE = "volunteers.txt";
        private readonly string ADMINS_FILE = "admins.txt";
        private readonly string HOSPITALS_FILE = "hospitals.txt";
        private readonly string HOSPITALPATIENTS_FILE = "hospitalpatients.txt";
        private readonly string USERS_FILE = "users.txt";
        private readonly string GROUPS_FILE = "groups.txt";
        private readonly string EVENTS_FILE = "events.txt";
        private readonly string POSTS_FILE = "posts.txt";
        private readonly string PHRASES_FILE = "phrases.txt";
        private readonly string MESSAGES_FILE = "messages.txt";
        private readonly string COMMENTS_FILE = "comments.txt";
        private readonly string GROUPMEMBERSHIP_FILE = "memberships.txt";
        private readonly string FRIENDSHIPS_FILE = "friendships.txt";
        private readonly string AVATARS_FILE = "avatars.txt";

        private string _dataFolderPath;

        public TextDataLoader(string dataFolderPath)
        {
            _dataFolderPath = dataFolderPath;
        }

        public void LoadQuestions()
        {
            var questions = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, QUESTIONS_FILE))
                             let c = line.Split(new char[] { ';' })
                             select new Question(
                                 c[5],
                                 c[0],
                                 c[1],
                                 DateTime.Parse(c[6], new CultureInfo("es-es", false))
                             ) { RowKey = c[2], Tags = c[4] }).ToList();

            questions.ForEach(q => QueryRepository.Add(q));
        }

        public void LoadAnswers()
        {
            var answers = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, ANSWERS_FILE))
                           let c = line.Split(new char[] { ';' })
                           select new Answer (
                                         c[2],
                                         c[1],
                                         c[0]
                                     )).ToList();

            answers.ForEach(a => AnswersRepository.Add(a));
        }

        public void LoadAnswerVotes()
        {
            var answersVotes = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, ANSWERSVOTES_FILE))
                                let c = line.Split(new char[] { ';' })
                                select new AnswerVote (
                                                c[1],
                                                c[0],
                                                Int32.Parse(c[2])
                                           )).ToList();

            answersVotes.ForEach(av => AnswersVotesRepository.Add(av));
        }

        public void LoadVolunteers()
        {
            var volunteers = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, VOLUNTEERS_FILE))
                              let c = line.Split(new char[] { ';' })
                              select new HelpRelationship(c[0], c[1])).ToList();

            volunteers.ForEach(v => HelpRelationshipRepository.Add(v));
        }

        public void LoadAdmins()
        {
            var admins = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, ADMINS_FILE))
                          let c = line.Split(new char[] { ';' })
                          select new Admin(c[0])).ToList();

            admins.ForEach(a => AdminsRepository.Add(a));
        }

        public void LoadHospitals()
        {
            var hospitals = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, HOSPITALS_FILE))
                             let c = line.Split(new char[] { ';' })
                             select new Hospital(
                                        c[1],
                                        c[2],
                                        c[3],
                                        c[4],
                                        c[5]
                                    )).ToList();

            hospitals.ForEach(h => HospitalsRepository.Add(h));
        }

        public void LoadHospitalPatients()
        {
            var hospitalpatients = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, HOSPITALPATIENTS_FILE))
                                    let c = line.Split(new char[] { ';' })
                                    select new HospitalPatient(c[0], c[1])).ToList();

            hospitalpatients.ForEach(hp => HospitalPatientsRepository.Add(hp));
        }

        public void LoadUsers()
        {
            var users = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, USERS_FILE))
                         let c = line.Split(new char[] { ';' })
                         select new User(c[0], c[1], c[2], c[3], bool.Parse(c[4]), int.Parse(c[5]), c[6], c[7], c[8], c[9], c[10], c[11], c[12], Boolean.Parse(c[13]), Boolean.Parse(c[14]))).ToList();

            users.ForEach(u => UsersRepository.Add(u));
        }

        public void LoadGroups()
        {
            var groups = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, GROUPS_FILE))
                          let c = line.Split(new char[] { ';' })
                          select new Group(c[0],c[1],c[2],c[3],c[4],c[5],c[6])).ToList();

            groups.ForEach(g => GroupsRepository.Add(g));
        }

        public void LoadEvents()
        {
            var events = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, EVENTS_FILE))
                          let c = line.Split(new char[] { ';' })
                          select new Event(c[0], c[1], c[2], DateTime.Parse(c[3],new CultureInfo("es-es", false)), c[4], int.Parse(c[5]))).ToList();

            events.ForEach(e => EventsRepository.Add(e));
        }

        public void LoadPosts()
        {
            var posts = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, POSTS_FILE))
                          let c = line.Split(new char[] { ';' })
                          select new Post(c[0], c[1], c[2], c[3], c[4]) { RowKey = c[5] }).ToList();

             posts.ForEach(p => PostsRepository.Add(p));
        }

        public void LoadPhrases()
        {
            var phrases = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, PHRASES_FILE))
                           let c = line.Split(new char[] { ';' })
                           select new Phrase(c[0], c[1], c[2])).ToList();

            phrases.ForEach(p => PhrasesRepository.Add(p));
        }

        public void LoadMessages()
        {
            var messages = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, MESSAGES_FILE))
                            let c = line.Split(new char[] { ';' })
                            select new Message(c[0], c[1], c[2], new List<string>(c.ToList().Skip(3)))).ToList();

            messages.ForEach(m => MessagesRepository.Add(m));
        }

        public void LoadComments()
        {
            var comments = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, COMMENTS_FILE))
                            let c = line.Split(new char[] { ';' })
                            select new Comment(c[0], c[1], c[2])).ToList();

            comments.ForEach(c => CommentsRepository.Add(c));
        }

        public void LoadGroupMemberships()
        {
            var memberships = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, GROUPMEMBERSHIP_FILE))
                               let c = line.Split(new char[] { ';' })
                               select new GroupMembership(c[0], c[1])).ToList();

            memberships.ForEach(gm => GroupMembershipsRepository.Add(gm));
        }

        public void LoadFriendships()
        {
            var friendships = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, FRIENDSHIPS_FILE))
                               let c = line.Split(new char[] { ';' })
                               select new Friendship(c[0], c[1])).ToList();

            friendships.ForEach(f => FriendshipsRepository.Add(f));
        }

        public void LoadAvatars()
        {
            var avatars = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, AVATARS_FILE))
                           let c = line.Split(new char[] { ';' })
                           let s = File.Open(c[1],FileMode.Open)
                           select new Avatar(c[0], null, c[2], s, c[3])).ToList();

            avatars.ForEach(a => AvatarsRepository.Add(a));
        }

        public void LoadAll()
        {
            LoadUsers();
            LoadAdmins();
            LoadAnswers();
            LoadAnswerVotes();
            LoadComments();
            LoadEvents();
            LoadFriendships();
            LoadGroupMemberships();
            LoadGroups();
            LoadHospitalPatients();
            LoadHospitals();
            LoadMessages();
            LoadPhrases();
            LoadPosts();
            LoadQuestions();
            LoadVolunteers();
            LoadAvatars();
        }

        public void DeleteAllAvatars()
        {
            var avatars = (from line in File.ReadAllLines(Path.Combine(_dataFolderPath, AVATARS_FILE))
                           let c = line.Split(new char[] { ';' })
                           let s = File.Open(c[1], FileMode.Open)
                           select new Avatar(c[0], null, c[2], s, c[3])).ToList();

            avatars.ForEach(a => AvatarsRepository.Delete(a));
        }

        public void DeleteAll()
        {
            UsersRepository.DeleteAllEntities();
            GroupsRepository.DeleteAllEntities();
            PostsRepository.DeleteAllEntities();
            QueryRepository.DeleteAllEntities();
            AnswersRepository.DeleteAllEntities();
            AnswersVotesRepository.DeleteAllEntities();
            HelpRelationshipRepository.DeleteAllEntities();
            AdminsRepository.DeleteAllEntities();
            HospitalsRepository.DeleteAllEntities();
            HospitalPatientsRepository.DeleteAllEntities();
            EventsRepository.DeleteAllEntities();
            PhrasesRepository.DeleteAllEntities();
            MessagesRepository.DeleteAllEntities();
            MessagesRecipentsRepository.DeleteAllEntities();
            CommentsRepository.DeleteAllEntities();
            GroupMembershipsRepository.DeleteAllEntities();
            FriendshipsRepository.DeleteAllEntities();
            DeleteAllAvatars();
        }

        [Dependency]
        public IQuestionsRepository QueryRepository { get; set; }
        [Dependency]
        public IAnswersRepository AnswersRepository { get; set; }
        [Dependency]
        public IAnswersVotesRepository AnswersVotesRepository { get; set; }
        [Dependency]
        public IHelpRelationshipsRepository HelpRelationshipRepository { get; set; }
        [Dependency]
        public IAdminsRepository AdminsRepository { get; set; }
        [Dependency]
        public IHospitalsRepository HospitalsRepository { get; set; }
        [Dependency]
        public IHospitalPatientsRepository HospitalPatientsRepository { get; set; }
        [Dependency]
        public IUsersRepository UsersRepository { get; set; }
        [Dependency]
        public IGroupsRepository GroupsRepository { get; set; }
        [Dependency]
        public IEventsRepository EventsRepository { get; set; }
        [Dependency]
        public IPostsRepository PostsRepository { get; set; }
        [Dependency]
        public IPhrasesRepository PhrasesRepository { get; set; }
        [Dependency]
        public IMessagesRepository MessagesRepository { get; set; }
        [Dependency]
        public IMessagesRecipentsRepository MessagesRecipentsRepository { get; set; }
        [Dependency]
        public ICommentsRepository CommentsRepository { get; set; }
        [Dependency]
        public IGroupMembershipsRepository GroupMembershipsRepository { get; set; }
        [Dependency]
        public IFriendshipsRepository FriendshipsRepository { get; set; }
        [Dependency]
        public IAvatarsRepository AvatarsRepository { get; set; }
    }
}
